#!/usr/bin/env jruby

require 'irb'
require 'repl'
require 'friendly_java'
require 'find'

# from the cookbook...
module Find
  def match(*paths)
    matched = []
    find(*paths) { |path| matched << path if yield path }
    return matched
  end
  module_function :match
end

# Find the processing libraries
possible_files = Find.match("../") { |f| f.include? '/lib/core.jar' }

if possible_files.length == 0 then
  possible_files = Find.match(ENV['HOME'] + "/bin") { |f| f.include? '/lib/core.jar' }
end

if possible_files.length == 0 then
  puts "Can't find Processing lib/core.jar anywhere. GAME OVER."
  exit
end

processing = possible_files.pop.sub('/lib/core.jar', '')

jars = %w{
  /lib/core.jar
  /libraries/opengl/library/opengl.jar
  /libraries/opengl/library/jogl.jar
  /libraries/physics/library/physics.jar
  /libraries/minim/library/minim.jar
  /libraries/minim/library/jl1.0.jar
  /libraries/minim/library/mp3spi1.9.4.jar
  /libraries/minim/library/tritonus_aos.jar
  /libraries/minim/library/tritonus_share.jar
  /libraries/Ess/library/Ess.jar
}

jars.each do |x|
  file = processing + x
  if File.exist? file
    require file
  else
    puts "Unable to find processing library #{x}"
  end
end

friendly_class "processing.core.PApplet"


# TODO: Make other useful Java/Processing modules optionally load in a nicer way

require 'processing'

module IRB
  # Override this, it eats our options and loads files and we want to do 
  # that our own jankity selves
  def self.parse_opts
  end

  def self.prep_session(binding)
    IRB.setup(nil)

    workspace = WorkSpace.new(binding)

    if @CONF[:SCRIPT]
      irb = Irb.new(workspace, @CONF[:SCRIPT])
    else
      irb = Irb.new(workspace)
    end

    @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
    @CONF[:MAIN_CONTEXT] = irb.context

    # TODO: THIS DOESN'T WORK IN JRUBY
    # (but it might in 1.1?)
    trap("SIGINT") do
      irb.signal_handle
    end

    return irb
  end

  def self.start_session irb
    catch(:IRB_EXIT) do
      irb.eval_input
    end
  end
end


# Auto-start the last subclass of Sketch defined and execute IRB in its binding scope
def run(file)
  load file
  puts "Starting latest sketch: " + Sketch.last_inherited.to_s
  $irb = IRB.prep_session(binding)
  $irb.context.evaluate "$sketch = Sketch.last_inherited.new", 1
  $irb.context.evaluate "$sketch.display", 1
  
  # TODO: This doesn't work. Not sure why.
  # irb.context.evaluate "irb sketch", 1
  # But this does!
  $irb.context.evaluate "irb $sketch.container", 1
  IRB.start_session $irb
end

def reload
  puts "Reloading..."
  load ARGV[0]
  load "processing.rb"
  # TODO: Thread to reload these files when they change
  
  # This looks strange, but it finds the global sketch's main container, 
  # and re-evaluates its container method (which re-fills it in with its 
  # objects and code) -- thus, reloading the entire sketch.
  $sketch.container.container
  $irb.context.evaluate "irb $sketch.container", 1
end

if ARGV[0]
  run(ARGV[0])
else
  IRB.start
end
